home *** CD-ROM | disk | FTP | other *** search
- /*
- ** FILE: ax25cmd.c
- **
- ** AX.25 command handler.
- **
- ** 09/24/90 Bob Applegate, wa2zzx
- ** Added BCTEXT, BC, and BCINTERVAL commands for broadcasting an id
- ** string using UI frames.
- */
-
- #include <stdio.h>
- #include <time.h>
- #include "global.h"
- #include "config.h"
- #include "mbuf.h"
- #include "timer.h"
- #include "proc.h"
- #include "iface.h"
- #include "ax25.h"
- #include "cmdparse.h"
- #include "socket.h"
- #include "mailbox.h"
- #include "session.h"
- #include "tty.h"
- #include "nr4.h"
- #include "commands.h"
- #include "asy.h"
- #ifdef SCC
- #include "scc.h"
- #endif
- #ifdef DRSI
- #include "drsi.h"
- #endif
- #ifdef VANESSA
- #include "vanessa.h"
- #endif
-
- #define next_seq(n) (((n) + 1) & 7)
-
- /* Defaults for IDing... */
- static char Axbctext[256];
- static struct timer Broadtimer; /* timer for broadcasts */
-
- int32 Axholdtime = AXROUTEHOLDTIME;
-
- static struct iface * near cmp_if __ARGS((char *ifname));
- static void near ax_bc __ARGS((struct iface *axif));
- /* static int near axheard __ARGS((struct iface *ifp)); */
- static char * near pathtostr __ARGS((struct ax25_cb *cp));
- static int doroutestat __ARGS((int argc,char *argv[],void *p));
-
- char *Ax25states[] = {
- "",
- "Disconnected",
- "Listen",
- "Conn pending",
- "Disc pending",
- "Connected",
- };
-
- char *Ax25reasons[] = {
- "Normal",
- "Reset",
- "Timeout",
- "Network",
- };
-
- static struct iface * near
- cmp_if(char *ifname)
- {
- struct iface *ifp;
-
- if((ifp = if_lookup(ifname)) == NULLIF) {
- tprintf(Badif,ifname);
- return NULLIF;
- }
- if(ifp->output != ax_output) {
- tprintf(Badax,ifname);
- return NULLIF;
- }
- return ifp;
- }
-
- /* This is the low-level broadcast function. */
- static void near
- ax_bc(axif)
- struct iface *axif;
- {
- /* prepare the header */
- int i = strlen(Axbctext);
- struct mbuf *hbp = ambufw(i);
-
- hbp->cnt = i;
- memcpy(hbp->data,Axbctext,i);
-
- (*axif->output)(axif,Ax25multi[2],axif->hwaddr,PID_NO_L3,hbp); /* send it */
- }
-
- /* This function is called to send the current broadcast message
- * and reset the timer. */
- static int
- dobc(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
- int i;
-
- for(i = 1; i < argc; i++)
- if((ifp = cmp_if(argv[i])) != NULLIF)
- ax_bc(ifp);
- return;
- }
-
- /* View/Change the message we broadcast. */
- static int
- dobctext(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int i;
-
- if (argc < 2 && Axbctext[0] != '\0') {
- tprintf("%s\n",Axbctext);
- } else {
- Axbctext[0] = '\0';
-
- for (i = 1; i < argc; i++) {
- strcat(Axbctext,argv[i]);
- if(strlen(Axbctext) > 220)
- break;
- strcat(Axbctext," ");
- }
- if(strlen(Axbctext) > 2) {
- strcat(Axbctext,AX_EOL);
- strcat(Axbctext,"\0");
- } else
- Axbctext[0] = '\0';
- }
- return 0;
- }
-
- static void
- dobroadtick()
- {
- struct iface *ifp;
-
- stop_timer(&Broadtimer);
-
- for(ifp = Ifaces; ifp; ifp = ifp->next)
- if(ifp->output == ax_output)
- ax_bc(ifp);
-
- /* Restart timer */
- start_timer(&Broadtimer) ;
- }
-
- /* Examine/change the broadcast interval. */
- static int
- dobcint(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2) {
- tprintf("ID timer %lu/%lu s\n",
- read_timer(&Broadtimer)/1000L,
- dur_timer(&Broadtimer)/1000L);
- } else {
- stop_timer(&Broadtimer) ; /* in case it's already running */
- /* what to call on timeout */
- Broadtimer.func = (void (*) __ARGS((void *))) dobroadtick;
- Broadtimer.arg = NULLCHAR; /* dummy value */
- /* set timer duration */
- set_timer(&Broadtimer,atol(argv[1]) * 1000L);
- start_timer(&Broadtimer); /* and fire it up */
- }
- return 0;
- }
-
- static int
- dobud(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char tmp[AXBUF];
-
- setcall(tmp,argv[1]);
- is_bud(tmp,1);
- return 0;
- }
-
- static int
- doaxclose(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct ax25_cb *axp = (struct ax25_cb *)ltop(htol(argv[1]));
-
- if(!ax25val(axp)){
- tputs(Notval);
- return 1;
- }
- return disc_ax25(axp);
- }
-
- static int
- doaxreset(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct ax25_cb *axp = (struct ax25_cb *)ltop(htol(argv[1]));
-
- if(!ax25val(axp)){
- tputs(Notval);
- return 1;
- }
- return reset_ax25(axp);
- }
-
- static int near
- axheard(ifp,tp)
- struct iface *ifp;
- char *tp;
- {
- int j, pid;
- char tmp[AXBUF], *cp;
- struct lq *lp;
- char type[8]; /* Type of traffic heard (TCP/IP, AX.25 etc) */
-
- if(ifp->hwaddr == NULLCHAR)
- return 0;
-
- for(lp = ifp->lq, j = 0; j < ifp->Hcurrent; lp++, j++) {
- if(j == 0) {
- if(tp != NULLCHAR)
- tprintf("Iface: %s\n%-12s%-28s%-11s%-15s\n",
- ifp->name,
- "Call",
- "Last Heard",
- "Traffic",
- "Packets");
- }
- pid = (int)lp->pid;
- cp = ctime(&lp->time);
- cp[24] = '\0';
-
- if (pid == PID_IP)
- strcpy(type, "TCP/IP");
- else if (pid == PID_ARP)
- strcpy(type, "ARP");
- else if (pid == PID_TEXNET)
- strcpy(type, "TexNet");
- else if (pid == PID_X25)
- strcpy(type, "X.25");
- else if (pid == PID_SEGMENT)
- strcpy(type, "SegFrag");
- else if (pid == PID_FLEXNET)
- strcpy(type, "FlexNet");
- else if (pid == PID_NETROM)
- strcpy(type, "NET/ROM");
- else if (pid == PID_NO_L3)
- strcpy(type, "IP/CAM");
- else
- strcpy(type, "AX.25");
-
- tprintf("%-12s%-28s%-11s%-15ld\n",pax25(tmp,lp->addr),
- cp,type,lp->currxcnt);
-
- }
- return 0;
- }
-
- int
- doaxheard(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- tprintf("System time: %s",ctime(&currtime));
-
- if(argc > 1){
- if((ifp = cmp_if(argv[1])) != NULLIF)
- axheard(ifp);
- return 0;
- }
- for(ifp = Ifaces;ifp != NULLIF;ifp = ifp->next){
- if(ifp->output != ax_output)
- continue; /* Not an ax.25 interface */
- axheard(ifp);
- }
- return 0;
- }
-
- static int
- doaxflush(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- for(ifp = Ifaces;ifp != NULLIF;ifp = ifp->next){
- if(ifp->output == ax_output)
- axflush(ifp);
- }
- return 0;
- }
-
- static char * near
- pathtostr(cp)
- struct ax25_cb *cp;
- {
-
- char *ap, *p;
- static char buf[128];
-
- if (!cp->pathlen) return "*";
- p = buf;
- ap = cp->path + AXALEN;
- if (!addreq(ap,cp->iface->hwaddr)) {
- pax25(p, ap);
- while (*p) p++;
- *p++ = '-';
- *p++ = '>';
- }
- pax25(p, cp->path);
- while (*p) p++;
- while (!(ap[6] & E)) {
- ap += AXALEN;
- *p++ = ',';
- pax25(p, ap);
- while (*p) p++;
- if (ap[6] & REPEATED) *p++ = '*';
- }
- *p = '\0';
- return buf;
- }
-
- /* Dump one control block */
- void
- st_ax25(struct ax25_cb *cp) {
- int i;
-
- tprintf("Path: %s\nIface: %s State: %s DAMA: %s\n",
- pathtostr(cp),
- cp->iface ? cp->iface->name : "???",
- Ax25states[cp->state],
- cp->dama ? "Yes" : "No");
-
- tprintf("Closed: %-5sPolling: %-5sREJsent: %-5sRNRsent: %-6sRNRrecv: ",
- cp->closed ? "Yes" : "No",
- cp->polling ? "Yes" : "No",
- cp->rejsent ? "Yes" : "No",
- cp->rnrsent ? "Yes" : "No");
-
- if (cp->remotebusy)
- tprintf("%ld sec", currtime - cp->remotebusy);
- else
- tputs("No");
-
- tprintf("\nCWind: %-6dRetry: %-7dUnack: %-7dSRT: %2ld sec Mdev: %2ld sec\nT1: ",
- cp->cwind,cp->retries,cp->unack,
- cp->srt / 1000L,cp->mdev / 1000L);
-
- if (run_timer(&cp->t1))
- tprintf("%ld",read_timer(&cp->t1) / 1000L);
- else
- tputs("-");
- tprintf("/%ld sec T2: ",dur_timer(&cp->t1) / 1000L);
- if (run_timer(&cp->t2))
- tprintf("%ld",read_timer(&cp->t2) / 1000L);
- else
- tputs("-");
- tprintf("/%ld sec T3: ",dur_timer(&cp->t2) / 1000L);
- if (run_timer(&cp->t3))
- tprintf("%ld",read_timer(&cp->t3) / 1000L);
- else
- tputs("-");
- tprintf("/%ld sec T4: ",dur_timer(&cp->t3) / 1000L);
- if (run_timer(&cp->t4))
- tprintf("%ld",read_timer(&cp->t4) / 1000L);
- else
- tputs("-");
- tprintf("/%ld sec T5: ",dur_timer(&cp->t4) / 1000L);
- if (run_timer(&cp->t5))
- tprintf("%ld",read_timer(&cp->t5) / 1000L);
- else
- tputs("-");
- tprintf("/%ld sec\nT6: ",dur_timer(&cp->t5) / 1000L);
- if (run_timer(&cp->t6) && cp->dama)
- tprintf("%ld",read_timer(&cp->t6) / 1000L);
- else
- tputs("-");
- tprintf("/%ld sec\n",dur_timer(&cp->t6) / 1000L);
-
- if(cp->rxq)
- tprintf("Rcv queue: %d\n", len_p(cp->rxq));
-
- if (cp->reseq[0].bp || cp->reseq[1].bp ||
- cp->reseq[2].bp || cp->reseq[3].bp ||
- cp->reseq[4].bp || cp->reseq[5].bp ||
- cp->reseq[6].bp || cp->reseq[7].bp) {
- tputs("Reassembly queue:\n");
- for (i = next_seq(cp->vr); i != cp->vr; i = next_seq(i))
- if (cp->reseq[i].bp)
- tprintf(" Seq %3d: %3d bytes\n",i,len_p(cp->reseq[i].bp));
- }
- if(cp->txq)
- tprintf("Snd queue: %d\n", len_p(cp->txq));
-
- if (cp->rxasm) {
- struct mbuf *bp;
- tputs("Resend queue:\n");
- for (i = 0, bp = cp->rxasm; bp; i++, bp = bp->anext)
- tprintf(" Seq %3d: %3d bytes\n",(cp->vs - cp->unack + i) & 7, len_p(bp));
- }
- return;
- }
-
- /* Display AX.25 link level control blocks */
- static int
- doaxstat(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct ax25_cb *axp;
- char tmp[AXBUF];
-
- if(argc < 2){
- tputs("&AXCB Rcv-Q Snd-Q Local Remote Iface State\n");
- for(axp = Ax25_cb; axp != NULLAX25; axp = axp->next){
- if(axp->state == LISTEN) {
- tprintf("%8lx%54s\n",ptol(axp),"Listen (S)");
- continue;
- }
- tprintf("%8lx%6d%6d %-10s",
- ptol(axp),len_p(axp->rxq),len_p(axp->txq),pax25(tmp,axp->path + AXALEN));
- tprintf("%-10s%-10s%s\n",
- pax25(tmp,axp->path),
- axp->iface ? axp->iface->name : "???",
- Ax25states[axp->state]);
- }
- return 0;
- }
- axp = (struct ax25_cb *)ltop(htol(argv[1]));
- if(!ax25val(axp)){
- tputs(Notval);
- return 1;
- }
- if(axp->state != LISTEN) {
- tprintf("&AXCB %lx &Peer %lx\n",ptol(axp),ptol(axp->peer));
- st_ax25(axp);
- }
- return 0;
- }
-
- /* Display or change our AX.25 address */
- static int
- domycall(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char tmp[AXBUF];
-
- if(argc < 2){
- tprintf("%s\n",pax25(tmp,Mycall));
- } else {
- if(setcall(Mycall,argv[1]) == -1)
- return -1;
- }
- return 0;
- }
-
- /* Control AX.25 digipeating */
- static int
- dodigipeat(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->digipeat,"Digipeat",--argc,++argv,0,2);
- return -1;
- }
-
- static int
- dot1(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->t1init,"T1init",--argc,++argv,3,30);
- return -1;
- }
-
- static int
- dot2(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->t2init,"T2init",--argc,++argv,0,ifp->flags->t1init/2);
- return -1;
- }
-
- static int
- dot3(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->t3init,"T3init",--argc,++argv,0,3600);
- return -1;
- }
-
- static int
- dot4(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->t4init,"T4init",--argc,++argv,ifp->flags->t1init*2,ifp->flags->t1init*20);
- return -1;
- }
-
- static int
- dot5(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->t5init,"T5init",--argc,++argv,0,ifp->flags->t2init-1);
- return -1;
- }
-
- static int
- dot6(int argc,char *argv[],void *p) {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->t6init,"T6init",--argc,++argv,180,ifp->flags->t3init-1);
- return -1;
- }
-
-
- /* Set retry limit count */
- static int
- doretries(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->retries,"Retries",--argc,++argv,0,50);
- return -1;
- }
-
- /* Force a retransmission */
- static int
- doaxkick(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct ax25_cb *axp = (struct ax25_cb *)ltop(htol(argv[1]));
-
- if(!ax25val(axp)){
- tputs(Notval);
- return 1;
- }
- kick_ax25(axp);
- return 0;
- }
-
- /* Set maximum number of frames that will be allowed in flight */
- static int
- domaxframe(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->maxframe,"Maxframe",--argc,++argv,1,7);
- return -1;
- }
-
- static int
- domaxheard(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF) {
- if(argc < 3)
- return(setint(&ifp->Hmax,"Maxheard",--argc,++argv));
- else
- return(maxheard(ifp,atoi(argv[2])));
- }
- return -1;
- }
-
- static int
- dot3disc(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setbool(&ifp->flags->t3disc,"T3disc",--argc,++argv);
- return -1;
- }
-
- /* Set maximum length of I-frame data field */
- static int
- dopaclen(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->paclen,"Paclen",--argc,++argv,1,2048);
- return -1;
- }
-
- /* Set size of I-frame above which polls will be sent after a timeout */
- static int
- dopthresh(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->pthresh,"Pthresh",--argc,++argv,0,ifp->flags->paclen);
- return -1;
- }
-
- /* Set high water mark on receive queue that triggers RNR */
- static int
- doaxwindow(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
-
- if((ifp = cmp_if(argv[1])) != NULLIF)
- return setintrc(&ifp->flags->axwindow,"Axwindow",
- --argc,++argv,ifp->flags->paclen/2,ifp->flags->paclen*8);
- return -1;
- }
- /* End of ax25 subcommands */
-
- /* Initiate interactive AX.25 connect to remote station */
- int
- doconnect(argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- char *ap, tmp[AXBUF], path[10*AXALEN];
- struct session *sp;
- struct iface *ifp = NULLIF;
- struct sockaddr_ax fsocket;
- struct ax25_cb axp;
-
- argc--;
- argv++;
-
- if((ifp = if_lookup(*argv)) != NULLIF) {
- if(ifp->output != ax_output) {
- tprintf(Badax,*argv);
- return 1;
- }
- argc--;
- argv++;
- }
- for (ap = path; argc > 0; argc--, argv++) {
- if (!strncmp("via", *argv, strlen(*argv))) continue;
- if (ap >= path + sizeof(path)) {
- tputs("Max 8 digis\n");
- return 1;
- }
- if (setcall(ap, *argv)) {
- tprintf("Invalid call %s\n", *argv);
- return 1;
- }
- ap[ALEN] &= ~E;
-
- if (ap == path) {
- ap += AXALEN;
- addrcp(ap,Mycall);
- ap[ALEN] &= ~E;
- }
- ap += AXALEN;
- }
- if (ap < path + 2 * AXALEN) {
- tputs("Missing call\n");
- return 1;
- }
- ap[-1] |= E;
-
- memset(&axp,0,sizeof(struct ax25_cb));
-
- build_path(&axp,ifp,path,0,0);
-
- if(!axp.iface) {
- tputs("No specified iface\n");
- return 1;
- }
-
- addrcp(axp.path + AXALEN,axp.iface->hwaddr);
- axroute_add(&axp,0);
-
- /* Allocate a session descriptor */
- if((sp = newsession(pax25(tmp,axp.path),AX25TNC,1,1)) == NULLSESSION){
- tputs(Nosess);
- return 1;
- }
-
- if((sp->s = socket(AF_AX25,SOCK_STREAM,0)) == -1){
- tputs(Nosocket);
- goto quit;
- }
-
- fsocket.sax_family = AF_AX25;
- memcpy(fsocket.ax25_addr,axp.path,AXALEN);
- memcpy(fsocket.iface,axp.iface->name,ILEN);
- if(!(tel_connect(sp, (char *)&fsocket, sizeof(struct sockaddr_ax))))
- return 0;
- quit:
- keywait(NULLCHAR,1);
- freesession(sp);
- return 1;
- }
-
- static int
- dorouteadd(argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
-
- char *ap;
- int perm;
- struct ax25_cb cb;
-
- argc--;
- argv++;
-
- if ((perm = !strcmp(*argv, "permanent")) != 0) {
- argc--;
- argv++;
- }
- if ((cb.iface = cmp_if(*argv)) == NULLIF)
- return 1;
-
- argc--;
- argv++;
-
- if (!strcmp(*argv,"default")) {
- axroute_default_ifp = cb.iface;
- return 0;
- }
- for (ap = cb.path; argc > 0; argc--, argv++) {
- if (!strncmp("via", *argv, strlen(*argv)))
- continue;
- if (ap >= cb.path + sizeof(cb.path)) {
- tputs("Max 8 digis\n");
- return 1;
- }
- if (setcall(ap, *argv)) {
- tprintf("Invalid call %s\n", *argv);
- return 1;
- }
- if (ap == cb.path) {
- ap += AXALEN;
- addrcp(ap,cb.iface->hwaddr);
- }
- ap += AXALEN;
- }
- if (ap < cb.path + 2 * AXALEN) {
- tputs("Missing call\n");
- return 1;
- }
- ap[-1] |= E;
- cb.pathlen = (int)(ap - cb.path);
- axroute_add(&cb, perm);
- return 0;
- }
-
- #include "smtp.h" /* for 'Months' */
-
- void
- doroutelistentry(rp)
- struct axroute_tab *rp;
- {
- char *cp, *buf = mxallocw(10*AXBUF);
- int i, n, perm = rp->perm;
- struct axroute_tab *rp_stack[20];
- struct iface *ifp;
- struct tm *tm = gmtime(&rp->time);
-
- pax25(cp = buf, (char *) &rp->call);
-
- for (n = 0; rp; rp = rp->digi) {
- rp_stack[++n] = rp;
- ifp = rp->ifp;
- }
- for (i = n; i > 1; i--) {
- strcat(cp, i == n ? " via " : ",");
- while (*cp) cp++;
- pax25(cp, (char *) &(rp_stack[i]->call));
- }
- tprintf("%2d-%.3s %02d:%02d %-9s %c %s\n",
- tm->tm_mday,
- Months[tm->tm_mon],
- /*
- "JanFebMarAprMayJunJulAugSepOctNovDec" + 3 * tm->tm_mon,
- */
- tm->tm_hour,
- tm->tm_min,
- ifp ? ifp->name : "???",
- perm ? '*' : ' ',
- buf);
- xfree(buf);
- }
-
- static int
- doroutelist(argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- int i;
- struct ax25_addr call;
- struct axroute_tab *rp;
- char tmp[AXBUF];
-
- tputs("Date GMT Interface P Path\n");
- if (argc < 2) {
- for (i = 0; i < AXROUTESIZE; i++)
- for (rp = axroute_tab[i]; rp; rp = rp->next)
- doroutelistentry(rp);
- } else {
- for (i = 1; i < argc; i++)
- if (setcall((char *) &call,argv[i]) || (rp = axroute_tabptr(&call,0)) == 0)
- tprintf("*** no route to %s\n",pax25(tmp,(char *) &call));
- else
- doroutelistentry(rp);
- }
- return 0;
- }
-
- static int
- doroutehold(argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- int16 holdtime = (int16)(Axholdtime / (60L*60*24));
-
- if(setintrc(&holdtime,"Holdtime (days)",argc,argv,1,120) == 0) {
- Axholdtime = (int32)(holdtime * 60L*60*24);
- return 0;
- }
- return 1;
- }
-
- static int
- doroutestat(argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- struct ifptable_t {
- struct iface *ifp;
- int count;
- } ;
-
- int i, dev, total;
- struct axroute_tab *rp, *dp;
- struct iface *ifp;
- struct ifptable_t ifptable[ASY_MAX
- #ifdef DRSI
- + DRMAX
- #endif
- #ifdef SCC
- + MAXSCC
- #endif
- #ifdef VANESSA
- + VAN_MAX
- #endif
- #ifdef AXIP
- + NAX25
- #endif
- ];
- memset(ifptable,0,sizeof(ifptable));
-
- for (ifp = Ifaces; ifp; ifp = ifp->next)
- if (ifp->output == ax_output)
- ifptable[ifp->niface].ifp = ifp;
-
- for (i = 0; i < AXROUTESIZE; i++) {
- for (rp = axroute_tab[i]; rp; rp = rp->next) {
- for (dp = rp; dp->digi; dp = dp->digi) ;
- if (dp->ifp)
- ifptable[dp->ifp->niface].count++;
- }
- }
- tputs("Interface Count\n");
- for (total = 0, dev = 0; dev < Niface; dev++) {
- if(ifptable[dev].count /*|| ifptable[dev].ifp == axroute_default_ifp*/) {
- tprintf("%c %-7s %5d\n",
- ifptable[dev].ifp == axroute_default_ifp ? '*' : ' ',
- ifptable[dev].ifp->name,
- ifptable[dev].count);
- total += ifptable[dev].count;
- }
- }
- tprintf(" total %5d\n", total);
- return 0;
- }
-
- /* Display and modify AX.25 routing table */
- static int
- doaxroute(argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- struct cmds routecmds[] = {
- "add", dorouteadd, 0, 3, "ax25 route add [permanent] <iface> <path>",
- "hold", doroutehold, 0, 0, NULLCHAR,
- "list", doroutelist, 0, 0, NULLCHAR,
- "stat", doroutestat, 0, 0, NULLCHAR,
- NULLCHAR, NULLFP, 0, 0, NULLCHAR
- };
-
- if (argc >= 2)
- return subcmd(routecmds, argc, argv, p);
- doroutestat(argc, argv, p);
- return 0;
- }
-
- /* Multiplexer for top-level ax25 command */
- int
- doax25(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct cmds Axcmds[] = {
- "bc", dobc, 0, 2, "ax25 bc <iface>",
- "bcinterval", dobcint, 0, 0, NULLCHAR,
- "bctext", dobctext, 0, 0, NULLCHAR,
- "bud", dobud, 0, 2, "ax25 bud <call>",
- "close", doaxclose, 0, 2, "ax25 close <axcb>",
- "digipeat", dodigipeat, 0, 2, "ax25 digipeat <iface>",
- "flush", doaxflush, 0, 0, NULLCHAR,
- "heard", doaxheard, 0, 0, NULLCHAR,
- "kick", doaxkick, 0, 2, "ax25 kick <axcb>",
- "maxframe", domaxframe, 0, 2, "ax25 maxframe <iface>",
- "maxheard", domaxheard, 0, 2, "ax25 maxheard <iface>",
- "mycall", domycall, 0, 0, NULLCHAR,
- "paclen", dopaclen, 0, 2, "ax25 paclen <iface>",
- "pthresh", dopthresh, 0, 0, NULLCHAR,
- "reset", doaxreset, 0, 2, "ax25 reset <axcb>",
- "retry", doretries, 0, 2, "ax25 retry <iface>",
- "route", doaxroute, 0, 0, NULLCHAR,
- "status", doaxstat, 0, 0, NULLCHAR,
- "t1", dot1, 0, 2, "ax25 t1 <iface>",
- "t2", dot2, 0, 2, "ax25 t2 <iface>",
- "t3", dot3, 0, 2, "ax25 t3 <iface>",
- "t3disc", dot3disc, 0, 2, "ax25 t3disc <iface>",
- "t4", dot4, 0, 2, "ax25 t4 <iface>",
- "t5", dot5, 0, 2, "ax25 t5 <iface>",
- "t6", dot6, 0, 2, "ax25 t6 <iface>",
- "window", doaxwindow, 0, 2, "ax25 window <iface>",
- NULLCHAR,
- };
- return subcmd(Axcmds,argc,argv,p);
- }
-